package com.arpa.wms.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.IterUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.arpa.ntocc.common.common.cache.AreaCache;
import com.arpa.ntocc.common.common.cache.PartyCache;
import com.arpa.ntocc.common.common.exception.ServiceException;
import com.arpa.ntocc.common.common.util.CommonUtil;
import com.arpa.ntocc.common.common.util.UserUtil;
import com.arpa.ntocc.common.domain.enums.CustomerCheckStatusEnum;
import com.arpa.wms.cache.CustomerCache;
import com.arpa.wms.common.util.UUIDUtil;
import com.arpa.wms.domain.consts.CommonConst;
import com.arpa.wms.domain.consts.NumConst;
import com.arpa.wms.domain.dto.CustomerDTO;
import com.arpa.wms.domain.entity.Customer;
import com.arpa.wms.domain.vo.CustomerVO;
import com.arpa.wms.mapper.CustomerMapper;
import com.arpa.wms.service.ICustomerService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * <p>
 * 客户 服务实现类
 * </p>
 *
 * @author LEO
 * @since 2020-09-04
 */
@Service
public class CustomerServiceImpl extends ServiceImpl<CustomerMapper, Customer> implements ICustomerService {

    private final CustomerCache customerCache;

    private final AreaCache areaCache;

    private final PartyCache partyCache;

    public CustomerServiceImpl(CustomerCache customerCache, AreaCache areaCache, PartyCache partyCache) {
        this.customerCache = customerCache;
        this.areaCache = areaCache;
        this.partyCache = partyCache;
    }

    private static final String THE_CUSTOMER_NAME_ALREADY_EXISTS = "客户名称已存在!";
    private static final String THE_CUSTOMER_NUMBER_ALREADY_EXISTS = "客户编号已存在!";
    /**
     * 保存
     *
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public boolean save(Customer entity) {
        //校验名称和编码是否重复
        CustomerDTO dto = new CustomerDTO();
        dto.setName(entity.getName());
        //保存当前所属机构标识
        dto.setGroupCode(UserUtil.getBranchCode());
        List<CustomerVO> name = queryByNameOrCode(dto);
        if (null != name && name.size() > 0) {

            throw new ServiceException(THE_CUSTOMER_NAME_ALREADY_EXISTS);
        }
        dto.setName("");
        dto.setCustomerCode(entity.getCustomerCode());
        List<CustomerVO> code = queryByNameOrCode(dto);
        if (null != code && code.size() > 0) {
            throw new ServiceException(THE_CUSTOMER_NUMBER_ALREADY_EXISTS);
        }

        if (StringUtils.isBlank(entity.getCode())) {
            entity.setCode(IdUtil.simpleUUID());
        }
        if (StringUtils.isBlank(entity.getCreatedBy())) {
            entity.setCreatedBy(UserUtil.getCode());
        }
        entity.setCode(UUIDUtil.getUUID32());
        entity.setCreatedBy(UserUtil.getCode());

        //清除旧缓存
        customerCache.flushAllCacheByGroupCode(UserUtil.getBranchCode());
        return super.save(entity);
    }

    /**
     * 根据code更新实体
     *
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public int updateByCode(Customer entity) {
        if(entity.getStatus().equals(NumConst.NUM_TWO)){
            entity.setStatus(NumConst.NUM_ZERO);
        }
        CustomerDTO dto = new CustomerDTO();
        dto.setName(entity.getName());
//        List<CustomerVO> name = queryByNameOrCode(dto);
//        if (null != name && name.size() > NumConst.NUM_ZERO) {
//            CustomerVO customerVO = name.get(NumConst.NUM_ZERO);
//            if (!customerVO.getCode().equals(entity.getCode())) {
//                throw new ServiceException(THE_CUSTOMER_NAME_ALREADY_EXISTS);
//            }
//        }
//        dto.setName("");
        dto.setCustomerCode(entity.getCustomerCode());
//        List<CustomerVO> code = queryByNameOrCode(dto);
//        if (null != code && code.size() > NumConst.NUM_ZERO) {
//            CustomerVO customerVO = code.get(NumConst.NUM_ZERO);
//            if (!customerVO.getCode().equals(entity.getCode())) {
//                throw new ServiceException(THE_CUSTOMER_NUMBER_ALREADY_EXISTS);
//            }
//        }

        if (StringUtils.isBlank(entity.getModifiedBy())) {
            entity.setModifiedBy(UserUtil.getCode());
        }

        //清除旧缓存
        customerCache.flushCache(entity.getCode(),UserUtil.getBranchCode());
        return baseMapper.update(entity, new QueryWrapper<Customer>().lambda().eq(Customer::getCode, entity.getCode()));
    }

    /**
     * 查询列表
     *
     * @param customerDTO
     * @return
     */
    @Override
    public List<CustomerVO> queryList(CustomerDTO customerDTO) {
        //排序字段名需要驼峰转数据库下划线类型字段名
        if (StringUtils.isNotEmpty(customerDTO.getSortField())) {
            customerDTO.setSortField(CommonUtil.camel2Underline(customerDTO.getSortField()));
        }
        List<CustomerVO> customerVOList = baseMapper.queryList(customerDTO);
        customerVOList.forEach(e -> {
            CustomerCheckStatusEnum enumByCode = CustomerCheckStatusEnum.getEnumByCode(e.getStatus());
            if (null != enumByCode) {
                e.setStatusText(enumByCode.getDesc());
            }
        });


        return customerVOList;
    }

    @Override
    public List<CustomerVO> queryByNameOrCode(CustomerDTO customerDTO) {

        return baseMapper.queryByNameOrCode(customerDTO);
    }

    /**
     * 查询合计,包含总数
     *
     * @param customerDTO
     * @return
     */
    @Override
    public CustomerVO queryListSum(CustomerDTO customerDTO) {
        CustomerVO customerVO = baseMapper.queryListSum(customerDTO);
        return customerVO;
    }

    @Override
    public int batchDelete(List<String> codes, String modifiedBy) {

        //清除旧缓存
        customerCache.flushAllCacheByGroupCode(UserUtil.getBranchCode());
        return baseMapper.batchDelete(codes, modifiedBy);
    }

    @Override
    public List<CustomerVO> findCustomer() {
        List<CustomerVO> customerVOS = this.customerCache.getAllByGroupCode(UserUtil.getBranchCode()).stream()
                .map(m -> BeanUtil.mapToBean(m, CustomerVO.class, false))
                .collect(Collectors.toList());
        return customerVOS;
    }

    /**
     * 添加客户信息
     *
     * @param dto
     */
    @Override
    public boolean save(CustomerDTO dto) {
        Customer entity = new Customer();
        BeanUtil.copyProperties(dto, entity);
        List<String> areaList = dto.getAreaList();
        if (IterUtil.isNotEmpty(areaList) && areaList.size() == NumConst.NUM_FOUR) {
            entity.setCountry(areaList.get(NumConst.NUM_ZERO));
            entity.setProvince(areaList.get(NumConst.NUM_ONE));
            entity.setCity(areaList.get(NumConst.NUM_TWO));
            entity.setCounty(areaList.get(NumConst.NUM_THREE));
        }

        int count = baseMapper.selectCount(new QueryWrapper<Customer>().lambda().eq(Customer::getCustomerCode, entity.getCustomerCode()).eq(Customer::getGroupCode,UserUtil.getBranchCode()));
        if (count > NumConst.NUM_ZERO) {
            throw new ServiceException(THE_CUSTOMER_NUMBER_ALREADY_EXISTS);
        }
        count = baseMapper.selectCount(new QueryWrapper<Customer>().lambda().eq(Customer::getName, entity.getName()).eq(Customer::getGroupCode,UserUtil.getBranchCode()));
        if (count > NumConst.NUM_ZERO) {
            throw new ServiceException(THE_CUSTOMER_NAME_ALREADY_EXISTS);
        }
        entity.setStatus(NumConst.NUM_ZERO);
        entity.setCode(UUIDUtil.getUUID32());
        entity.setGroupCode(UserUtil.getBranchCode());
        entity.setCreatedBy(UserUtil.getCode());
        entity.setCreatedName(partyCache.translate(UserUtil.getCode()));
        entity.setModifiedBy(UserUtil.getCode());
        entity.setModifiedName(partyCache.translate(UserUtil.getCode()));
        customerCache.flushAllCacheByGroupCode(UserUtil.getBranchCode());
        return super.save(entity);
    }

    /**
     * 获取客户信息
     *
     * @param code 客户code
     * @return
     */
    @Override
    public CustomerVO getOneInfo(String code) {
        Map<String, Object> customerMap = customerCache.get(code);
        CustomerVO entity = BeanUtil.mapToBean(customerMap, CustomerVO.class, false);
        Optional.ofNullable(entity).orElseThrow(() -> new ServiceException("没有查询到信息"));
        List<String> areaList = new ArrayList<>();
        areaList.add(entity.getCountry());
        areaList.add(entity.getProvince());
        areaList.add(entity.getCity());
        areaList.add(entity.getCounty());
        String areaStr = "";
        if (StrUtil.isNotBlank(entity.getCountry())) {
            areaStr = areaCache.translateCountry(entity.getCountry());
        }

        if (StrUtil.isNotBlank(entity.getProvince())) {
            if (StrUtil.isNotBlank(areaStr)) {
                areaStr = areaStr + "/" + areaCache.translateProvince(entity.getProvince());
            } else {
                areaStr = areaCache.translateProvince(entity.getProvince());
            }
        }
        if (StrUtil.isNotBlank(entity.getCity())) {
            if (StrUtil.isNotBlank(areaStr)) {
                areaStr = areaStr + "/" + areaCache.translateCity(entity.getCity());
            } else {
                areaStr = areaCache.translateCity(entity.getCity());
            }
        }
        if (StrUtil.isNotBlank(entity.getCounty())) {
            if (StrUtil.isNotBlank(areaStr)) {
                areaStr = areaStr + "/" + areaCache.translateCounty(entity.getCounty());
            } else {
                areaStr = areaCache.translateCounty(entity.getCounty());
            }
        }


        entity.setArea(areaStr);
        entity.setAreaList(areaList);
        return entity;
    }

    /**
     * 更新客户信息
     *
     * @param entity
     * @return
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public int  updateByCode(CustomerDTO entity) {
        Customer customerDb = baseMapper.selectOne(new QueryWrapper<Customer>().lambda().eq(Customer::getCode, entity.getCode()).eq(Customer::getGroupCode,UserUtil.getBranchCode()));
        Optional.ofNullable(customerDb).orElseThrow(() -> new ServiceException("查不到供应商信息"));
        Customer customer = new Customer();
        BeanUtil.copyProperties(entity, customer);
        customer.setCustomerCode(customerDb.getCustomerCode());
        List<String> areaList = entity.getAreaList();
        if (IterUtil.isNotEmpty(areaList) && areaList.size() == NumConst.NUM_FOUR) {
            customer.setCountry(areaList.get(NumConst.NUM_ZERO));
            customer.setProvince(areaList.get(NumConst.NUM_ONE));
            customer.setCity(areaList.get(NumConst.NUM_TWO));
            customer.setCounty(areaList.get(NumConst.NUM_THREE));
        }

        customer.setModifiedBy(UserUtil.getCode());
        customer.setModifiedName(partyCache.translate(UserUtil.getCode()));
        return updateByCode(customer);
    }

    /**
     * 客户信息审核
     *
     * @param code   客户code
     * @param status 审核状态 1：通过。2不通过
     * @return
     */
    @Override
    public boolean approve(String code, int status) {
        boolean bool = this.update(new UpdateWrapper<Customer>().lambda().eq(Customer::getCode, code).eq(Customer::getStatus, 0).set(Customer::getStatus, status).eq(Customer::getGroupCode, UserUtil.getBranchCode()));
        if (bool) {
            customerCache.flushCache(code,UserUtil.getBranchCode());
        }
        return bool;
    }

    /**
     * 调整排序字段
     * @param customerDTO
     * @return
     */
    @Override
    public CustomerDTO adjustSortFields(CustomerDTO customerDTO){
        if ("statusText".equals(customerDTO.getSortField())) {
            customerDTO.setSortField(CommonConst.STATUS);
        }
        return customerDTO;
    }


}
